﻿using Google.Protobuf.WellKnownTypes;
using IoTClient.Clients.Modbus;
using IoTClient.Enums;
using IoTClient.Models;
using IoTClient;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using S7Simulate.Config;

namespace S7Simulate.Utils
{
    /// <summary>
    /// IOT操作PLC工具类
    /// </summary>
    class PLCOperateUtil
    {
        //创建PLC连接
        public ModbusTcpClient ModbusTcpClient = null;
        public PLCOperateUtil()
        {
            if (CommonbaseConfig.BaseConfig != null)
            {
                ModbusTcpClient = new ModbusTcpClient(CommonbaseConfig.BaseConfig.PLCIP, int.Parse(CommonbaseConfig.BaseConfig.PLCPort), 2000, format: EndianFormat.CDAB);
                Connect();
            }
        }
        public void Connect()
        {
            ModbusTcpClient.Open();
        }
        public bool GetConnectedStatus()
        {
            if (ModbusTcpClient == null)
            {
                return false;
            }
            return ModbusTcpClient.Connected;
        }
        public bool SendCommand()
        {
            try
            {
                if (ModbusTcpClient == null) { return false; }
                var re = ModbusTcpClient.ReadInt32(Convert.ToInt16(3000).ToString());
                return re.IsSucceed;
            }
            catch (Exception)
            {
                return false;
            }
        }
        public void Close()
        {
            try
            {
                if (ModbusTcpClient != null)
                {
                    ModbusTcpClient.Close();
                }
            }
            catch (Exception)
            {

            }
        }
        public void WriteBool(string address, bool value)
        {
            try
            {
                if (ModbusTcpClient == null) { return; }
                var writeResult = ModbusTcpClient.Write(address, value);
                if (!writeResult.IsSucceed)
                {
                    Log4NetHelper.Error($"WriteBool：{address}-{value}");
                }
            }
            catch (Exception e)
            {
                Log4NetHelper.Error($"{e.Message};地址：{address};值：{value}");
            }
        }
        public void WriteString(string address, string value, bool isReverse = false)
        {
            try
            {
                if (ModbusTcpClient == null) { return; }
                var q = Encoding.ASCII.GetBytes(value);
                if (isReverse)
                {
                    q = q.Reverse().ToArray();
                }
                var writeResult = ModbusTcpClient.Write(address, q);
                if (!writeResult.IsSucceed)
                {
                    Log4NetHelper.Error($"WriteString：{address}-{value}");
                }
            }
            catch (Exception e)
            {
                Log4NetHelper.Error($"{e.Message};地址：{address};值：{value}");
            }
        }
        public void WriteInt(string address, int value)
        {
            try
            {
                if (ModbusTcpClient == null) { return; }
                var writeResult = ModbusTcpClient.Write(address, value);
                if (!writeResult.IsSucceed)
                {
                    Log4NetHelper.Error($"WriteInt：{address}-{value}");
                }
            }
            catch (Exception e)
            {
                Log4NetHelper.Error($"{e.Message};地址：{address};值：{value}");
            }
        }

        public void WriteUShort(string address, ushort value)
        {
            try
            {
                if (ModbusTcpClient == null) { return; }
                var writeResult = ModbusTcpClient.Write(address, value);

                if (!writeResult.IsSucceed)
                {
                    Log4NetHelper.Error($"WriteUShort：{address}-{value}");
                }
            }
            catch (Exception e)
            {
                Log4NetHelper.Error($"{e.Message};地址：{address};值：{value}");
            }
        }
        public string ReadCodes(string address)
        {
            if (ModbusTcpClient == null) { return ""; }
            StringBuilder stringBuilder = new StringBuilder();
            var re = ModbusTcpClient.Read(address.ToString(), 1, 3, 8);
            if (re.IsSucceed)
            {
                stringBuilder.Append(Encoding.ASCII.GetString(re.Value.Reverse().ToArray()));
            }
            return stringBuilder.ToString().Replace("\0", string.Empty);
        }

        public bool ReadCoil(string address)
        {
            try
            {
                if (ModbusTcpClient == null) { return false; }
                var readResult = ModbusTcpClient.ReadCoil(address);
                if (!readResult.IsSucceed)
                {
                    Log4NetHelper.Error($"ReadCoil：{address}");
                    return false;
                }
                return readResult.Value;
            }
            catch (Exception e)
            {
                Log4NetHelper.Error(e.ToString());
                return false;
            }
        }
        public int ReadInt(string address)
        {
            try
            {
                if (ModbusTcpClient == null) { return 0; }
                var readResult = ModbusTcpClient.ReadInt32(address);
                if (!readResult.IsSucceed)
                {
                    Log4NetHelper.Error($"ReadInt：{address}");
                    return 0;
                }
                return readResult.Value;
            }
            catch (Exception e)
            {
                Log4NetHelper.Error(e.ToString());
                return 0;
            }
        }
        public string ReadCode(string address,bool isRes = false)
        {
            if (ModbusTcpClient == null) {
                Log4NetHelper.Debug($"ModbusTcpClient--null");
                return ""; }
            StringBuilder stringBuilder = new StringBuilder();
            var re = ModbusTcpClient.Read(address.ToString(), 1, 3, 14);
            if (re.IsSucceed && isRes)
            {
                stringBuilder.Append(Encoding.ASCII.GetString(re.Value.Reverse().ToArray()));
            }
            else
            {
                stringBuilder.Append(Encoding.ASCII.GetString(re.Value.ToArray()));
            }
            return stringBuilder.ToString().Replace("\0", string.Empty);
        }

        public Result<List<ModbusOutput>> BatchRead(List<ModbusInput> addresses)
        {
            try
            {
                if (ModbusTcpClient == null) { return null; }
                var readResult = ModbusTcpClient.BatchRead(addresses);
                if (!readResult.IsSucceed)
                {
                    return null;
                }
                return readResult;
            }
            catch (Exception e)
            {
                Log4NetHelper.Error(e.ToString());
                return null;
            }
        }
    }
}
